home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / C Internet Config / IC Component Source ƒ / 68k Version ƒ / IC Link In.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-06  |  37.0 KB  |  1,306 lines  |  [TEXT/SPM ]

  1. /*
  2.     IC Link In.c
  3.     
  4.     Main code for accessing the configuration file.  This code can be linked in to an application
  5.     (if the component is not available) to provide access to the IC prefs file.
  6.     
  7.     This code represents the lowest-level of access to the config file.
  8.     
  9.     History
  10.         11/06/95 dhn - Started C port.
  11. */
  12.  
  13. /*
  14.     Original pascal comment:
  15.     
  16.         (* File:         ICLinkIn.p
  17.          * Generated by: 1.0d4
  18.          * For:          IC 1.2
  19.          * On:           Monday, 25 September 1995, 19:28:12
  20.          * 
  21.          * This file is part of the Internet Configuration system and
  22.          * is placed in the public domain for the benefit of all.
  23.          *)
  24. */
  25.  
  26. #include <Components.h>
  27. #include <AppleTalk.h>
  28. #include <Folders.h>
  29. #include <Processes.h>
  30. #include <Errors.h>
  31. #include <AppleEvents.h>
  32. #include <LowMem.h>
  33.  
  34. #include "IC Types.h"
  35. #include "IC Keys.h"
  36.  
  37. #include "IC Resource API.h"
  38. #include "IC Link In Subs.h"
  39.  
  40. #define kICOurManufacturer    'JPQE'
  41. #define kRes_Code            'ICRP'
  42.  
  43. // Local Prototypes
  44. #ifdef __cplusplus
  45. extern "C" {
  46. #endif
  47.  
  48. OSErr ICFindFolder(short vRefNum,OSType folderType,Boolean createFolder,short* foundVRefNum,long* foundDirID);
  49. Boolean ICRCloseIfOpen(ICRRecordPtr inst);
  50. ICError ValidDirSpec(ICDirSpec* folder);
  51. OSErr FoundFile(ICDirSpec* folder,short ndx,FSSpec* found_file);
  52. Boolean ScanFolder(ICRRecordPtr inst,ICDirSpec* folder,FSSpecPtr found_file);
  53. OSErr FindPrefFolder(ICDirSpec* pref_fold);
  54. void SetSFCWD(ICRRecordPtr inst);
  55. ICError GetFile(ICRRecordPtr inst,FSSpecPtr fs);
  56. ICError PutFile(ICRRecord* inst,FSSpecPtr fs);
  57. short ICRPermToFSPerm(ICPerm perm);
  58. ICError ICRCheckInside(ICRRecord* inst);
  59. ICError ICRForceInside(ICRRecord* inst,ICPerm perm,Boolean* force_info);
  60. ICError ICRReleaseInside(ICRRecord* inst,Boolean force_info);
  61. Boolean __URL_SpecStartChar(char ch);
  62. Boolean __URL_SpecEndChar(char ch);
  63. ICError ExpandSelection(char* datap,long len,long* selStart,long* selEnd);
  64. Boolean SpaceTab(char ch);
  65. Boolean SpaceTabRet(char ch);
  66. ICError ShrinkSelection(char* datap,long len,long* selStart,long* selEnd);
  67. ICError StripReturns(Handle urlh);
  68. void UnpackCopyString(Ptr* p,StringPtr s);
  69. OSErr UnpackEntry(Handle entries,long pos,ICMapEntry* entry,long* user_length);
  70. OSErr FastGetEntry(Handle entries,long pos,ICMapEntry* entry);
  71. void PackCopyString(ICMapEntry* entry,Ptr p,StringPtr s);
  72. void PackEntry(ICMapEntry* entry,Ptr p,long user_length);
  73. short GetShort(Ptr P);
  74. char UpCase(char ch);
  75. Boolean IsExtensionVar(StringPtr name,StringPtr ext);
  76.  
  77. Boolean HasResourceFork(const FSSpec* file);
  78. OSErr EnsureResourceFork(const FSSpec* file);
  79.  
  80. #ifdef __cplusplus
  81. }
  82. #endif
  83.  
  84. /*
  85.     HasResourceFork
  86.     EnsureResourceFork
  87.     
  88.     The IC pieces have one bug (that I have found).  Although they ensure that a file exists when selecting one
  89.     (either through the Find, FindUser, FindGeneral, or SpecifyConfigFile routines), they don't ensure that the
  90.     files have a resource fork.  That means that whatever piece is specifying the file *must* get everything right.
  91.     
  92.     HasResourceFork and EnsureResourceFork will check the config file; if it has a resource fork, nothing is done.
  93.     If the file doesn't have a resource fork, one will be added.
  94. */
  95. Boolean HasResourceFork(const FSSpec* spec){
  96.     HParamBlockRec pbr;
  97.     OSErr err;
  98.     
  99.     pbr.fileParam.ioCompletion=0;
  100.     pbr.fileParam.ioVRefNum=spec->vRefNum;
  101.     pbr.fileParam.ioFDirIndex=0;
  102.     pbr.fileParam.ioNamePtr=(StringPtr)spec->name;
  103.     pbr.fileParam.ioDirID=spec->parID;
  104.     
  105.     err=PBHGetFInfo(&pbr,false);
  106.     if (err!=noErr)
  107.         return false;
  108.     
  109.     /*
  110.         If a file has a resource fork, even an empty one, a resource map will still exist for the file,
  111.         therefore the ioFlRLgLen (which contains the length of the resource fork) will be some number
  112.         greater than zero if the file has a resource fork.
  113.     */
  114.     return (pbr.fileParam.ioFlRLgLen>0);
  115. }
  116.  
  117. OSErr EnsureResourceFork(const FSSpec* spec){
  118.     HParamBlockRec pbr;
  119.     OSErr err;
  120.     
  121.     pbr.fileParam.ioCompletion=0;
  122.     pbr.fileParam.ioVRefNum=spec->vRefNum;
  123.     pbr.fileParam.ioFDirIndex=0;
  124.     pbr.fileParam.ioNamePtr=(StringPtr)spec->name;
  125.     pbr.fileParam.ioDirID=spec->parID;
  126.     
  127.     err=PBHGetFInfo(&pbr,false);
  128.     
  129.     if (err==fnfErr){
  130.         // then the file doesn't exist, but is being put in a default place so it really should be there
  131.     } else if (err!=noErr)
  132.         return err;
  133.     
  134.     if (pbr.fileParam.ioFlRLgLen<=0){
  135.         // file doesn't have a resource fork, create one for the file
  136.         HCreateResFile(spec->vRefNum,spec->parID,spec->name);
  137.         return ResError();
  138.     }
  139.     return noErr;
  140. }
  141.  
  142. /*
  143.     ICFindFolder
  144.     
  145.     converted from the pascal wrapper function to call the FindFolder trap.
  146.     
  147.     Was declared as:
  148.         
  149.         inline $7000,$A823
  150. */
  151. OSErr ICFindFolder(short vRefNum,OSType folderType,Boolean createFolder,short* foundVRefNum,long* foundDirID){
  152.     return FindFolder(vRefNum,folderType,createFolder,foundVRefNum,foundDirID);
  153. }
  154.  
  155. ICError ICRStart(ICRRecordPtr inst,OSType creator){
  156.     ICError err;
  157.     Str255 defPrompt="\pCreate configuration as:";
  158.     
  159.     if (inst==(ICRRecordPtr)0)
  160.         return (ICError)paramErr;
  161.     
  162.     inst->have_config_file=false;
  163.     inst->config_file.vRefNum=0;
  164.     inst->config_file.parID=0;
  165.     inst->config_file.name[0]=0;
  166.     inst->config_refnum=0;
  167.     inst->perm=icNoPerm;
  168.     
  169.     BlockMoveData((Ptr)defPrompt,(Ptr)inst->prompt,defPrompt[0]+2);
  170.     
  171.     ICRDefaultFileName(inst,inst->default_filename);
  172.     
  173.     return noErr;
  174. }
  175.  
  176. Boolean ICRCloseIfOpen(ICRRecordPtr inst){
  177.     Boolean ret=inst->perm!=icNoPerm;
  178.     
  179.     if (inst->config_refnum!=0){
  180.         CloseResFile(inst->config_refnum);
  181.         inst->config_refnum=0;
  182.     }
  183.     
  184.     inst->perm=icNoPerm;
  185.     
  186.     return ret;
  187. }
  188.  
  189. ICError ICRStop(ICRRecordPtr inst){
  190.     
  191.     if (inst==(ICRRecordPtr)0)
  192.         return (ICError)paramErr;
  193.     
  194.     if (ICRCloseIfOpen(inst))
  195.         return (ICError)paramErr;
  196.     
  197.     return (ICError)noErr;
  198. }
  199.  
  200.  
  201. ICError ValidDirSpec(ICDirSpec* folder){
  202.     CInfoPBRec cpb;
  203.     
  204.     cpb.hFileInfo.ioVRefNum=folder->vRefNum;
  205.     cpb.hFileInfo.ioDirID=folder->dirID;
  206.     cpb.hFileInfo.ioNamePtr=(StringPtr)0;
  207.     cpb.hFileInfo.ioFDirIndex=-1;
  208.     
  209.     return (ICError)PBGetCatInfoSync(&cpb);
  210. }
  211.  
  212. OSErr FoundFile(ICDirSpec* folder,short ndx,FSSpec* found_file){
  213.     OSErr err;
  214.     CInfoPBRec cpb;
  215.     Boolean is_folder;
  216.     Boolean was_alias;
  217.     long response;
  218.     
  219.     cpb.hFileInfo.ioVRefNum=folder->vRefNum;
  220.     cpb.hFileInfo.ioDirID=folder->dirID;
  221.     cpb.hFileInfo.ioNamePtr=found_file->name;
  222.     cpb.hFileInfo.ioFDirIndex=ndx;
  223.     
  224.     err=PBGetCatInfoSync(&cpb);
  225.     
  226.     if (err==noErr){
  227.         found_file->vRefNum=cpb.hFileInfo.ioVRefNum;
  228.         found_file->parID=cpb.hFileInfo.ioFlParID;
  229.         
  230.         if ((cpb.hFileInfo.ioFlAttrib&(16))||(cpb.hFileInfo.ioFlFndrInfo.fdType!=kICFileType)){
  231.             err=(OSErr)1;
  232.         } else if ((Gestalt(gestaltAliasMgrAttr,&response)==noErr)&&(BitTst(&response,(31-gestaltAliasMgrPresent)))){
  233.             err=ResolveAliasFile(found_file,true,&is_folder,&was_alias);
  234.             
  235.             if (err!=noErr)
  236.                 err=(OSErr)1;
  237.         }
  238.     }
  239.     
  240.     return err;
  241. }
  242.  
  243. Boolean ScanFolder(ICRRecordPtr inst,ICDirSpec* folder,FSSpecPtr found_file){
  244.     ICError err;
  245.     Boolean found;
  246.     register short i;
  247.     
  248.     BlockMoveData((Ptr)inst->default_filename,(Ptr)found_file->name,inst->default_filename[0]+1);
  249.     
  250.     found=(FoundFile(folder,0,found_file)==noErr);
  251.     
  252.     if (!found){
  253.         i=1;
  254.         
  255.         do {
  256.             found_file->name[0]=0;
  257.             err=FoundFile(folder,i,found_file);
  258.             i++;
  259.         } while (err!=1);
  260.         
  261.         found=(err==noErr);
  262.     }
  263.     
  264.     return found;
  265. }
  266.  
  267. ICError ICRFindConfigFile(ICRRecordPtr inst,short count,ICDirSpecArrayPtr folders){
  268.     return ICRGeneralFindConfigFile(inst,true,true,count,folders);
  269. }
  270.  
  271. ICError ICRFindUserConfigFile(ICRRecordPtr inst,ICDirSpec* where){
  272.     return ICRGeneralFindConfigFile(inst,false,true,1,where);
  273. }
  274.  
  275. OSErr FindPrefFolder(ICDirSpec* pref_fold){
  276.     OSErr err;
  277.     SysEnvRec env;
  278.     long response;
  279.     
  280.     err=Gestalt(gestaltFindFolderAttr,&response);
  281.     
  282.     if (err==noErr){
  283.         if (BitTst(&response,(31-gestaltFindFolderPresent)))
  284.             return ICFindFolder(kOnSystemDisk,kPreferencesFolderType,true,&(pref_fold->vRefNum),&(pref_fold->dirID));
  285.     }
  286.     
  287.     // otherwise simulate FindFolder
  288.     
  289.     err=SysEnvirons(curSysEnvVers,&env);
  290.     
  291.     if (err==noErr)
  292.         err=GetWDInfo(env.sysVRefNum,&(pref_fold->vRefNum),&(pref_fold->dirID),&response);
  293.     
  294.     return err;
  295. }
  296.  
  297. ICError ICRGeneralFindConfigFile(ICRRecordPtr inst,Boolean search_prefs,Boolean can_create,short count,ICDirSpecArrayPtr folders){
  298.     ICError err=noErr;
  299.     register short i=0;
  300.     Boolean found=false;
  301.     ICDirSpec pref_fold;
  302.     ICDirSpec* last_folder_scanned;
  303.     FSSpec temp_config_file;
  304.     HParamBlockRec pbr;
  305.     
  306.     inst->have_config_file=false;
  307.     
  308.     if (inst->perm!=icNoPerm)
  309.         return (ICError)paramErr;
  310.     
  311.     if ((count<0)||((count!=0)&&(folders==(ICDirSpecArrayPtr)0)))
  312.         return (ICError)paramErr;
  313.     
  314.     if ((count==0)&&(!search_prefs)&&(can_create))
  315.         return (ICError)paramErr;
  316.     
  317.     i=0;
  318.     while ((err==noErr)&&(i<count)){
  319.         err=ValidDirSpec(&(folders[i]));
  320.         i++;
  321.     }
  322.     
  323.     if (err!=noErr)
  324.         return err;
  325.     
  326.     i=0;
  327.     
  328.     while ((i<count)&&(!found)){
  329.         found=ScanFolder(inst,&(folders[i]),&temp_config_file);
  330.         
  331.         last_folder_scanned=&(folders[i]);
  332.         i++;
  333.     }
  334.     
  335.     if ((!found)&&(search_prefs)){
  336.         err=FindPrefFolder(&pref_fold);
  337.         
  338.         if (err==noErr){
  339.             found=ScanFolder(inst,&pref_fold,&temp_config_file);
  340.             last_folder_scanned=&pref_fold;
  341.         }
  342.     }
  343.     
  344.     if ((!found)&&(can_create)){
  345.         temp_config_file.vRefNum=last_folder_scanned->vRefNum;
  346.         temp_config_file.parID=last_folder_scanned->dirID;
  347.         BlockMoveData((Ptr)inst->default_filename,(Ptr)temp_config_file.name,inst->default_filename[0]+1);
  348.         found=true;
  349.     }
  350.     
  351.     if (!found)
  352.         err=icConfigNotFoundErr;
  353.     
  354.     if (err==noErr){
  355.         BlockMoveData((Ptr)&(temp_config_file),(Ptr)&(inst->config_file),sizeof(FSSpec));
  356.         inst->have_config_file=true;
  357.         
  358.         // Need to ensure that there is a resource fork for a file...
  359.         err=EnsureResourceFork(&(inst->config_file));
  360.     }
  361.     
  362.     return err;
  363. }
  364.  
  365. void SetSFCWD(ICRRecordPtr inst){
  366.     
  367.     if (inst->have_config_file){
  368.         LMSetCurDirStore(inst->config_file.parID);
  369.         LMSetSFSaveDisk(-(inst->config_file.vRefNum));
  370.     }
  371. }
  372.  
  373. ICError GetFile(ICRRecordPtr inst,FSSpecPtr fs){
  374.     ICError err=userCanceledErr;
  375.     SFTypeList typeList;
  376.     StandardFileReply nreply;
  377.     SFReply oreply;
  378.     long eric;
  379.     Point where;
  380.     
  381.     SetSFCWD(inst);
  382.     
  383.     typeList[0]=kICFileType;
  384.     
  385.     if (HaveNewStandardFile()){
  386.         StandardGetFile((FileFilterUPP)0,1,typeList,&nreply);
  387.         if (nreply.sfGood){
  388.             BlockMoveData((Ptr)&(nreply.sfFile),fs,sizeof(FSSpec));
  389.             err=noErr;
  390.         }
  391.     } else {
  392.         where.h=0x40;
  393.         where.v=0x40;
  394.         
  395.         SFGetFile(where,"\p",(FileFilterUPP)0,1,typeList,(DlgHookUPP)0,&oreply);
  396.         if (oreply.good){
  397.             err=GetWDInfo(oreply.vRefNum,&fs->vRefNum,&fs->parID,&eric);
  398.             BlockMoveData(oreply.fName,fs->name,oreply.fName[0]+1);
  399.         }
  400.     }
  401.     
  402.     return err;
  403. }
  404.  
  405. ICError PutFile(ICRRecord* inst,FSSpecPtr fs){
  406.     ICError err;
  407.     SFTypeList typeList;
  408.     StandardFileReply nreply;
  409.     SFReply oreply;
  410.     long eric;
  411.     Str63 defname;
  412.     
  413.     SetSFCWD(inst);
  414.     err=userCanceledErr;
  415.     typeList[0]=kICFileType;
  416.     
  417.     if (inst->have_config_file){
  418.         BlockMoveData(inst->config_file.name,defname,inst->config_file.name[0]+1);
  419.     } else {
  420.         BlockMoveData(inst->default_filename,defname,inst->default_filename[0]+1);
  421.     }
  422.     
  423.     if (HaveNewStandardFile()){
  424.         StandardPutFile(inst->prompt,defname,&nreply);
  425.         if (nreply.sfGood){
  426.             BlockMoveData((Ptr)&(nreply.sfFile),(Ptr)fs,sizeof(FSSpec));
  427.             err=noErr;
  428.         }
  429.     } else {
  430.         Point where;
  431.         
  432.         where.h=0x040;
  433.         where.v=0x040;
  434.         
  435.         SFPutFile(where,inst->prompt,defname,(DlgHookUPP)0,&oreply);
  436.         if (oreply.good){
  437.             err=GetWDInfo(oreply.vRefNum,&fs->vRefNum,&fs->parID,&eric);
  438.             BlockMoveData(oreply.fName,fs->name,oreply.fName[0]+1);
  439.         }
  440.     }
  441.     
  442.     return err;
  443. }
  444.  
  445. ICError ICRChooseConfig(ICRRecord* inst){
  446.     OSErr err=noErr;
  447.     FSSpec config;
  448.     
  449.     if (inst->perm!=icNoPerm)
  450.         return paramErr;
  451.     
  452.     err=CanInteract();
  453.     
  454.     if (err==noErr){
  455.         err=GetFile(inst,&config);
  456.     }
  457.     
  458.     if (err==noErr){
  459.         err=ICRSpecifyConfigFile(inst,&config);
  460.     }
  461.     
  462.     return err;
  463. }
  464.  
  465. ICError ICRChooseNewConfig(ICRRecord* inst){
  466.     OSErr err=noErr;
  467.     FSSpec config;
  468.     
  469.     if (inst->perm!=icNoPerm)
  470.         return paramErr;
  471.     
  472.     err=CanInteract();
  473.     
  474.     if (err==noErr)
  475.         err=PutFile(inst,&config);
  476.     
  477.     if (err==noErr){
  478.         HDelete(config.vRefNum,config.parID,config.name);
  479.         err=HCreate(config.vRefNum,config.parID,config.name,kICCreator,kICFileType);
  480.     }
  481.     
  482.     if (err==noErr)
  483.         err=ICRSpecifyConfigFile(inst,&config);
  484.     
  485.     return err;
  486. }
  487.  
  488. ICError ICRGetConfigName(ICRRecord* inst,Boolean longname,StringPtr name){
  489.     OSErr err=noErr;
  490.     
  491.     if (!inst->have_config_file)
  492.         return paramErr;
  493.     
  494.     if (!longname){
  495.         BlockMoveData(inst->config_file.name,name,inst->config_file.name[0]+1);
  496.         err=noErr;
  497.     } else {
  498.         err=FSSpecToFullPath(&(inst->config_file),name);
  499.     }
  500.     
  501.     return err;
  502. }
  503.  
  504. ICError ICRGetConfigReference(ICRRecord* inst,ICConfigRefHandle ref){
  505.     ICError err=noErr;
  506.     ICConfigRef header;
  507.     long loe;
  508.     
  509.     if (!inst->have_config_file)
  510.         return paramErr;
  511.     
  512.     if (ref==(ICConfigRefHandle)0)
  513.         return paramErr;
  514.     
  515.     err=FSSpecToICFileSpec(&(inst->config_file),(ICFileSpecHandle)ref);
  516.     
  517.     if (err==noErr){
  518.         header.manufacturer=kICOurManufacturer;
  519.         loe=Munger((Handle)ref,0,(Ptr)0,0,&header,sizeof(ICConfigRef));
  520.         err=MemError();
  521.     }
  522.     
  523.     if (err!=noErr)
  524.         SetHandleSize((Handle)ref,0);
  525.     
  526.     return err;
  527. }
  528.  
  529. ICError ICRSetConfigReference(ICRRecord* inst,ICConfigRefHandle ref,long flags){
  530.     ICError err;
  531.     ICFileSpecHandle filespec;
  532.     long loe;
  533.     FSSpec fs;
  534.     
  535.     if (inst->perm!=icNoPerm)
  536.         return paramErr;
  537.     
  538.     if (ref==(ICConfigRefHandle)0)
  539.         return paramErr;
  540.     
  541.     if (GetHandleSize((Handle)ref)<4)
  542.         return paramErr;
  543.     
  544.     if ((*ref)->manufacturer!=kICOurManufacturer)
  545.         return icConfigInappropriateErr;
  546.     
  547.     if (GetHandleSize((Handle)ref)<(sizeof(ICConfigRef)+sizeof(ICFileSpec)))
  548.         return paramErr;
  549.     
  550.     BlockMoveData((Ptr)ref,(Ptr)&filespec,sizeof(ICFileSpecHandle));
  551.     err=HandToHand((Handle*)(&filespec));
  552.     
  553.     if (err==noErr){
  554.         loe=Munger((Handle)filespec,0,(Ptr)0,sizeof(ICConfigRef),&loe,0);
  555.         err=ICFileSpecToFSSpec(filespec,!(flags&icNoUserInteraction_mask),&fs);
  556.         DisposeHandle((Handle)filespec);
  557.     }
  558.     
  559.     if (err==noErr)
  560.         ICRSpecifyConfigFile(inst,&fs);
  561.     
  562.     return err;
  563. }
  564.  
  565. ICError ICRSpecifyConfigFile(ICRRecord* inst,FSSpecPtr config){
  566.     ICError err;
  567.     ICDirSpec folder;
  568.     
  569.     if (inst->perm!=icNoPerm)
  570.         return paramErr;
  571.     
  572.     folder.vRefNum=config->vRefNum;
  573.     folder.dirID=config->parID;
  574.     
  575.     err=ValidDirSpec(&folder);
  576.     
  577.     if (err==noErr)
  578.         BlockMoveData((Ptr)config,(Ptr)&(inst->config_file),sizeof(FSSpec));
  579.     
  580.     inst->have_config_file=(err==noErr);
  581.     
  582.     if (inst->have_config_file){
  583.         // Need to ensure that there is a resource fork for a file...
  584.         err=EnsureResourceFork(&(inst->config_file));
  585.     }
  586.     
  587.     return err;
  588. }
  589.  
  590. ICError ICRGetSeed(ICRRecord* inst,long* seed){
  591.     ICError err;
  592.     CInfoPBRec cpb;
  593.     
  594.     *seed=0L;
  595.     err=fnfErr;
  596.     
  597.     if (inst->have_config_file){
  598.         cpb.hFileInfo.ioVRefNum=inst->config_file.vRefNum;
  599.         cpb.hFileInfo.ioDirID=inst->config_file.parID;
  600.         cpb.hFileInfo.ioNamePtr=inst->config_file.name;
  601.         cpb.hFileInfo.ioFDirIndex=0;
  602.         
  603.         err=PBGetCatInfoSync(&cpb);
  604.         
  605.         if (err==noErr)
  606.             *seed=cpb.hFileInfo.ioFlMdDat;
  607.         else if (err==fnfErr)
  608.             err=noErr;
  609.     }
  610.     
  611.     return err;
  612. }
  613.  
  614. ICError ICRGetPerm(ICRRecord* inst,ICPerm* perm){
  615.     *perm=inst->perm;
  616.     return noErr;
  617. }
  618.  
  619. short ICRPermToFSPerm(ICPerm perm){
  620.     switch (perm){
  621.         case icReadOnlyPerm:
  622.             return fsRdPerm;
  623.             break;
  624.         case icReadWritePerm:
  625.             return fsRdWrPerm;
  626.             break;
  627.         default:
  628.             return 0;
  629.             break;
  630.     }
  631.     
  632.     return 0;
  633. }
  634.  
  635. ICError ICRBegin(ICRRecord* inst,ICPerm perm){
  636.     ICError err;
  637.     short ref;
  638.     
  639.     if ((inst->perm!=icNoPerm)||(perm==icNoPerm))
  640.         return paramErr;
  641.     
  642.     if (!inst->have_config_file)
  643.         return bdNamErr;
  644.     
  645.     ref=FSpOpenResFile(&(inst->config_file),ICRPermToFSPerm(perm));
  646.     err=ResError();
  647.     
  648.     if ((err==fnfErr)||(err==eofErr)){
  649.         switch (perm){
  650.             case icReadOnlyPerm:
  651.                 ref=0;
  652.                 err=noErr;
  653.             f (err==noErr)
  654.         err=err2;
  655.     
  656.     return err;
  657. }
  658.  
  659. // I call ICRForceInside to speed this routine up.  ICRForceInside will do an ICRBegin and hence open the resource
  660. // file, which is good because otherwise I'd open it twice, once for each ICRGetPref.
  661.  
  662. ICError ICRFindPrefHandle(ICRRecord* inst,StringPtr key,ICAttr* attr,Handle prefh){
  663.     ICError err=noErr,err2=noErr;
  664.     long prefsize=0L;
  665.     Boolean force_info;
  666.     
  667.     if (prefh==(Handle)0)
  668.         err=paramErr;
  669.     
  670.     if (err==noErr){
  671.         err=ICRForceInside(inst,icReadOnlyPerm,&force_info);
  672.         if (err==noErr)
  673.             err=ICRGetPref(inst,key,attr,(Ptr)0,&prefsize);
  674.         
  675.         if (err==noErr){
  676.             SetHandleSize(prefh,prefsize);
  677.             err=MemError();
  678.         }
  679.         
  680.         if (err==noErr){
  681.             HLock(prefh);
  682.             err=ICRGetPref(inst,key,attr,*prefh,&prefsize);
  683.             HUnlock(prefh);
  684.         }
  685.         
  686.         err2=ICRReleaseInside(inst,force_info);
  687.     }
  688.     if (err==noErr)
  689.         err=err2;
  690.     
  691.     if ((prefh!=(Handle)0)&&(err!=noErr)){
  692.         SetHandleSize(prefh,0);
  693.     }
  694.     
  695.     return err;
  696. }
  697.  
  698. ICError ICRGetPrefHandle(ICRRecord* inst,StringPtr key,ICAttr* attr,Handle* prefh){
  699.     ICError err;
  700.     
  701.     *prefh=NewHandle(0);
  702.     err=MemError();
  703.     
  704.     if (err==noErr)
  705.         err=ICRFindPrefHandle(inst,key,attr,*prefh);
  706.     
  707.     if (err==icPrefNotFoundErr){
  708.         SetHandleSize(*prefh,0);
  709.         *attr=0;
  710.         err=noErr;
  711.     }
  712.     
  713.     return err;
  714. }
  715.  
  716. ICError ICRSetPrefHandle(ICRRecord* inst,StringPtr key,ICAttr attr,Handle prefh){
  717.     ICError err=noErr;
  718.     SignedByte s;
  719.     
  720.     if (prefh!=(Handle)0){
  721.         if (*prefh==(Ptr)0)
  722.             err=paramErr;
  723.         if (err==noErr){
  724.             s=HGetState(prefh);
  725.             HLock(prefh);
  726.             err=ICRSetPref(inst,key,attr,*prefh,GetHandleSize(prefh));
  727.             HSetState(prefh,s);
  728.         }
  729.     } else {
  730.         err=ICRSetPref(inst,key,attr,(Ptr)0,0);
  731.     }
  732.     
  733.     return err;
  734. }
  735.  
  736. ICError ICRCountPref(ICRRecord* inst,long* count){
  737.     ICError err;
  738.     short old_refnum;
  739.     
  740.     err=ICRCheckInside(inst);
  741.     if (err==noErr){
  742.         if (inst->config_refnum==0)
  743.             *count=0;
  744.         else {
  745.             old_refnum=CurResFile();
  746.             UseResFile(inst->config_refnum);
  747.             err=ResError();
  748.             if (err==noErr){
  749.                 *count=Count1Resources(kRes_Code);
  750.                 err=ResError();
  751.                 UseResFile(old_refnum);
  752.             }
  753.         }
  754.     }
  755.     
  756.     if (err!=noErr)
  757.         *count=0;
  758.     
  759.     return err;
  760. }
  761.  
  762. ICError ICRGetIndPref(ICRRecord* inst,long n,StringPtr key){
  763.     ICError err;
  764.     short old_refnum;
  765.     Handle prefh=(Handle)0;
  766.     short junk_id;
  767.     ResType junk_type;
  768.     
  769.     err=ICRCheckInside(inst);
  770.     if ((err==noErr)&&(n<1))
  771.         err=paramErr;
  772.     
  773.     if (err==noErr){
  774.         if (inst->config_refnum==0)
  775.             err=icPrefNotFoundErr;
  776.         else {
  777.             old_refnum=CurResFile();
  778.             UseResFile(inst->config_refnum);
  779.             err=ResError();
  780.             if (err==noErr){
  781.                 SetResLoad(false);
  782.                 prefh=Get1IndResource(kRes_Code,n);
  783.                 SetResLoad(true);
  784.                 
  785.                 if (prefh==(Handle)0)
  786.                     err=icPrefNotFoundErr;
  787.                 else {
  788.                     GetResInfo(prefh,&junk_id,&junk_type,key);
  789.                     err=ResError();
  790.                 }
  791.                 UseResFile(old_refnum);
  792.             }
  793.         }
  794.     }
  795.     
  796.     if (prefh!=(Handle)0)
  797.         ReleaseResource(prefh);
  798.     
  799.     return err;
  800. }
  801.  
  802. ICError ICRDeletePref(ICRRecord* inst,StringPtr key){
  803.     ICError err;
  804.     Handle prefh;
  805.     short old_refnum;
  806.     
  807.     err=ICRCheckInside(inst);
  808.     if ((err==noErr)&&(key[0]==0))
  809.         err=paramErr;
  810.     
  811.     if (err==noErr){
  812.         if (inst->config_refnum==0)
  813.             err=icPrefNotFoundErr;
  814.         else {
  815.             old_refnum=CurResFile();
  816.             UseResFile(inst->config_refnum);
  817.             err=ResError();
  818.             if (err==noErr){
  819.                 SetResLoad(false);
  820.                 prefh=Get1NamedResource(kRes_Code,key);
  821.                 err=ResError();
  822.                 SetResLoad(true);
  823.                 if (prefh==(Handle)0)
  824.                     err=icPrefNotFoundErr;
  825.                 else {
  826.                     RmveResource(prefh);
  827.                     DisposeHandle(prefh);
  828.                     err=ResError();
  829.                 }
  830.                 UseResFile(old_refnum);
  831.             }
  832.         }
  833.     }
  834.     
  835.     return err;
  836. }
  837.  
  838. ICError ICREnd(ICRRecord* inst){
  839.     ICError err;
  840.     
  841.     err=ICRCheckInside(inst);
  842.     ICRCloseIfOpen(inst);
  843.     
  844.     return err;
  845. }
  846.  
  847. ICError ICRDefaultFileName(ICRRecord* inst,StringPtr name){
  848.     Str63 lname=kICDefaultFileName;
  849.     
  850.     BlockMoveData(lname,name,lname[0]+1);
  851.     
  852.     return noErr;
  853. }
  854.  
  855. ICError ICREditPreferences(ICRRecord* inst,StringPtr key){
  856.     ICError err;
  857.     
  858.     if (!inst->have_config_file)
  859.         return bdNamErr;
  860.     
  861.     return EditPreferences(key,&(inst->config_file));
  862. }
  863.  
  864. /*
  865.     URL Parsing Algorithm
  866.  
  867.     1. if there is a selection skip to step 4
  868.     2. expand selection to end of word (never skip an a[0]=='<')&&(buf[bsize-1]=='>')){
  869.             doTrim=true;
  870.         }
  871.         
  872.         HSetState(urlh,s);
  873.         
  874.         if (doTrim){
  875.             SetHandleSize(urlh,bsize-1);
  876.             HUnlock(urlh);
  877.             // unlock before the munger call
  878.             Munger(urlh,0,(Ptr)0,1,(Ptr)-1,0);
  879.             HSetState(urlh,s);
  880.         }
  881.         
  882.         // trim off leading "\pURL:"
  883.         HLock(urlh);
  884.         if ((GetHandleSize(urlh)>tmp[0])&&(IUMagIDString(*urlh,&(tmp[1]),tmp[0],tmp[0])==0)){
  885.             HUnlock(urlh);
  886.             Munger(urlh,0,(Ptr)0,tmp[0],(Ptr)-1,0);
  887.         }
  888.         HSetState(urlh,s);
  889.         
  890.         // search for protocol
  891.         tmp[0]=1;tmp[1]=':';
  892.         HUnlock(urlh);
  893.         ndx=Munger(urlh,0,&(tmp[1]),1,(Ptr)0,0);
  894.         if ((ndx<0)||(ndx>255)){
  895.             // failed to find a colon in first 256 bytes,prepend "hint:" to url
  896.             if (hint[0]==0)
  897.                 err=icNoURLErr;
  898.             else {
  899.                 Munger(urlh,0,(Ptr)0,0,&(hint[1]),hint[0]);
  900.                 err=MemError();
  901.             }
  902.         }
  903.         HSetState(urlh,s);
  904.     }
  905.     return err;
  906. }
  907.  
  908. ICError ICRLaunchURL(ICRRecord* inst,StringPtr hint,Ptr data,long len,long* selStart,long* selEnd){
  909.     ICError err;
  910.     Handle urlh;
  911.     ICAppSpec helper;
  912.     Str255 scheme;
  913.     Str255 temp=kICHelper;
  914.     long junk_attr;
  915.     long size;
  916.     
  917.     urlh=NewHandle(0);
  918.     err=MemError();
  919.     
  920.     if (err==noErr)
  921.         err=ICRParseURL(inst,hint,data,len,selStart,selEnd,urlh);
  922.     else 
  923.         urlh=(Handle)0;
  924.     
  925.     if (err==noErr)
  926.         err=FindScheme(urlh,scheme);
  927.     
  928.     if (err==noErr){
  929.         size=sizeof(ICAppSpec);
  930.         BlockMoveData(scheme,(Ptr)&(temp[temp[0]+1]),scheme[0]);
  931.         temp[0]+=scheme[0];
  932.         err=ICRGetPref(inst,temp,&junk_attr,(Ptr)(&helper),&size);
  933.     }
  934.     
  935.     if (err==noErr)
  936.         err=LaunchURL(helper.fCreator,urlh);
  937.     
  938.     if (urlh!=(Handle)0)
  939.         DisposeHandle(urlh);
  940.     
  941.     return err;
  942. }
  943.  
  944. void UnpackCopyString(Ptr* p,StringPtr s){
  945.     short len;
  946.     
  947.     // calc the len of the current pascal string pointed to by p
  948.     len=((**p) & 0x00ff) +1;
  949.     
  950.     // copy the string in the buffer to s
  951.     BlockMoveData(*p,s,len);
  952.     
  953.     // move the pointer to the start of the next pascal string
  954.     *p=(Ptr)((*p)+len);
  955. }
  956.  
  957. // Internal Mapping Subs
  958. OSErr UnpackEntry(Handle entries,long pos,ICMapEntry* entry,long* user_length){
  959.     // WARNING: Depends very much on the exact format of ICMapEntry!
  960.     Ptr org,p;
  961.     long maxsize;
  962.     OSErr err=noErr;
  963.     
  964.     if ((entries==(Handle)0)||(*entries==(Ptr)0)||(pos<0)||(pos>GetHandleSize(entries)-6))
  965.         return paramErr;
  966.     
  967.     p=(Ptr)((*entries)+pos);
  968.     maxsize=GetHandleSize(entries);
  969.     org=p;
  970.     
  971.     BlockMoveData(p,(Ptr)entry,6);
  972.     
  973.     if ((entry->fixed_length!=ICmap_fixed_length)||(entry->fixed_length>entry->total_length)||(entry->total_length>maxsize))
  974.         return badExtResource;
  975.     
  976.     BlockMoveData(p,entry,entry->fixed_length);
  977.     p=(Ptr)(p+entry->fixed_length);
  978.     UnpackCopyString(&p,entry->extension);
  979.     UnpackCopyString(&p,entry->creator_app_name);
  980.     UnpackCopyString(&p,entry->post_app_name);
  981.     UnpackCopyString(&p,entry->MIME_type);
  982.     UnpackCopyString(&p,entry->entry_name);
  983.     
  984.     *user_length=entry->total_length-(p-org);
  985.     
  986.     return err;
  987. }
  988.  
  989. // a fast version of ICRGetEntry doesn't return all of the strings for the entry
  990. // WARNING: Depends very much on the exact format of ICMapEntry!
  991. OSErr FastGetEntry(Handle entries,long pos,ICMapEntry* entry){
  992.     Ptr org,p;
  993.     long maxsize;
  994.     OSErr err=noErr;
  995.     
  996.     if ((entries==(Handle)0)||(*entries==(Ptr)0)||(pos<0)||(pos>GetHandleSize(entries)-6))
  997.         return paramErr;
  998.     
  999.     p=(Ptr)((*entries)+pos);
  1000.     maxsize=GetHandleSize(entries);
  1001.     BlockMoveData(p,entry,6);
  1002.     
  1003.     if ((entry->fixed_length!=ICmap_fixed_length)||(entry->fixed_length>entry->total_length)||(entry->total_length>maxsize))
  1004.         return badExtResource;
  1005.     
  1006.     BlockMoveData(p,entry,entry->fixed_length);
  1007.     p=(Ptr)(p+entry->fixed_length);
  1008.     BlockMoveData(p,entry->extension,(((*p)&0x00ff)+1));
  1009.     return err;
  1010. }
  1011.  
  1012. void PackCopyString(ICMapEntry* entry,Ptr p,StringPtr s){
  1013.     
  1014.     BlockMoveData(s,(Ptr)(p+entry->total_length),s[0]+1);
  1015.     entry->total_length+=s[0]+1;
  1016. }
  1017.  
  1018. void PackEntry(ICMapEntry* entry,Ptr p,long user_length){
  1019.     Ptr a,b;
  1020.     
  1021.     entry->version=0;
  1022.     
  1023.     a=(Ptr)&(entry->extension);
  1024.     b=(Ptr)entry;
  1025.     
  1026.     entry->fixed_length=a-b;
  1027.     entry->total_length=entry->fixed_length;
  1028.     
  1029.     PackCopyString(entry,p,entry->extension);
  1030.     PackCopyString(entry,p,entry->creator_app_name);
  1031.     PackCopyString(entry,p,entry->post_app_name);
  1032.     PackCopyString(entry,p,entry->MIME_type);
  1033.     PackCopyString(entry,p,entry->entry_name);
  1034.     
  1035.     entry->total_length+=user_length;
  1036.     
  1037.     BlockMoveData(entry,p,entry->fixed_length);
  1038. }
  1039.  
  1040. short GetShort(Ptr P){
  1041.     unsigned char* p=(unsigned char*)P;
  1042.     short val=0;
  1043.     
  1044.     val=p[0];
  1045.     val <<= 8;
  1046.     val+=p[1];
  1047.     
  1048.     return val;
  1049. }
  1050.  
  1051. char UpCase(char ch){
  1052.     
  1053.     if ((ch>='a')&&(ch<='z'))
  1054.         return (ch-'a')+'A';
  1055.     
  1056.     return ch;
  1057. }
  1058.  
  1059. Boolean IsExtensionVar(StringPtr name,StringPtr ext){
  1060.     short pn,pe;
  1061.     
  1062.     if (name[0]>=ext[0]){
  1063.         pn=name[0]-ext[0]+1;
  1064.         pe=1;
  1065.         
  1066.         while (pe<=ext[0]){
  1067.             if (UpCase(name[pn])!=UpCase(ext[pe]))
  1068.                 break;
  1069.             
  1070.             pn++;
  1071.             pe++;
  1072.         }
  1073.         
  1074.         return pe>ext[0];
  1075.     }
  1076.     return false;
  1077. }
  1078.  
  1079. // Low Level Mapping Routines
  1080.  
  1081. ICError ICRCountMapEntries(ICRRecord* inst,Handle entries,long* count){
  1082.     Ptr p;
  1083.     long pos;
  1084.     short size;
  1085.     long hsize;
  1086.     
  1087.     if ((entries==(Handle)0)||(*entries==(Ptr)0))
  1088.         return paramErr;
  1089.     
  1090.     p=*entries;
  1091.     pos=0L;
  1092.     *count=0;
  1093.     hsize=GetHandleSize(entries);
  1094.     while (pos<hsize){
  1095.         size=GetShort(p); // extract the total_length value from the current pointer
  1096.         pos+=size; // add it to the pos offset
  1097.         p+=size; // add it to the pointer
  1098.         (*count)++; // increment the count
  1099.     }
  1100.     
  1101.     return noErr;
  1102. }
  1103.  
  1104. ICError ICRGetIndMapEntry(ICRRecord* inst,Handle entries,long ndx,long* pos,ICMapEntry* entry){
  1105.     ICError err;
  1106.     Ptr p;
  1107.     long i;
  1108.     short size;
  1109.     long hsize;
  1110.     
  1111.     if ((entries==(Handle)0)||(*entries==(Ptr)0)||(ndx<0))
  1112.         return paramErr;
  1113.     
  1114.     p=(Ptr)*entries;
  1115.     *pos=0;
  1116.     hsize=GetHandleSize(entries);
  1117.     
  1118.     while ((ndx>1)&&(*pos<hsize)){
  1119.         size=GetShort(p); // extract the total_length value from the current pointer
  1120.         *pos+=size; // add the size to the pos offset
  1121.         p+=size; // add the size to the pointer
  1122.         ndx--; // decrease the index for the entry
  1123.     }
  1124.     
  1125.     return ICRGetMapEntry(inst,entries,*pos,entry);
  1126. }
  1127.  
  1128. ICError ICRGetMapEntry(ICRRecord* inst,Handle entries,long pos,ICMapEntry* entry){
  1129.     ICError err;
  1130.     long user_length;
  1131.     
  1132.     if ((entries==(Handle)0)||(*entries==(Ptr)0)||(pos<0)||(pos>GetHandleSize(entries)))
  1133.         return paramErr;
  1134.     
  1135.     return UnpackEntry(entries,pos,entry,&user_length);
  1136. }
  1137.  
  1138. ICError ICRSetMapEntry(ICRRecord* inst,Handle entries,long pos,ICMapEntry* entry){
  1139.     ICError err;
  1140.     ICMapEntry e,oldentry;
  1141.     long user_length,source_length;
  1142.     
  1143.     if ((entries==(Handle)0)||(*entries==(Ptr)0)||(pos<0)||(pos>GetHandleSize(entries)))
  1144.         return paramErr;
  1145.     
  1146.     err=UnpackEntry(entries,pos,&oldentry,&user_length);
  1147.     
  1148.     if (err==noErr){
  1149.         PackEntry(entry,(Ptr)&e,user_length);
  1150.         source_length=oldentry.total_length-user_length;
  1151.         
  1152.         if (user_length<8){ // hack to remove alignment bytes from previous version
  1153.             source_length=oldentry.total_length;
  1154.             e.total_length=e.total_length-user_length;
  1155.             user_length=0;
  1156.         }
  1157.         Munger(entries,pos,(Ptr)0,source_length,&e,e.total_length-user_length);
  1158.         err=MemError();
  1159.     }
  1160.     
  1161.     return err;
  1162. }
  1163.  
  1164. ICError ICRDeleteMapEntry(ICRRecord* inst,Handle entries,long pos){
  1165.     ICError err;
  1166.     ICMapEntry entry;
  1167.     long user_length;
  1168.     
  1169.     if ((entries==(Handle)0)||(*entries==(Ptr)0)||(pos<0)||(pos>=GetHandleSize(entries)))
  1170.         return paramErr;
  1171.     
  1172.     err=UnpackEntry(entries,pos,&entry,&user_length);
  1173.     
  1174.     if (err==noErr){
  1175.         Munger(entries,pos,(Ptr)0,entry.total_length,(Ptr)-1,0);
  1176.         err=MemError();
  1177.     }
  1178.     
  1179.     return err;
  1180. }
  1181.  
  1182. ICError ICRAddMapEntry(ICRRecord* inst,Handle entries,ICMapEntry* entry){
  1183.     ICError err;
  1184.     ICMapEntry tmp_entry;
  1185.     
  1186.     if ((entries==(Handle)0)||(*entries==(Ptr)0))
  1187.         return paramErr;
  1188.     
  1189.     PackEntry(entry,(Ptr)&tmp_entry,0);
  1190.     
  1191.     return PtrAndHand(&tmp_entry,entries,entry->total_length);
  1192. }
  1193.  
  1194. // High Level Mapping Subs
  1195.  
  1196. ICError ICRMapEntriesFilename(ICRRecord* inst,Handle entries,StringPtr filename,ICMapEntry* entry){
  1197.     // Implementation lifted directly from Space Aliens
  1198.     ICError err;
  1199.     short longest_len;
  1200.     long posndx,found_pos;
  1201.     
  1202.     if ((entries==(Handle)0)||(*entries==(Ptr)0)||(filename[0]==0))
  1203.         return paramErr;
  1204.     
  1205.     // loop through the entries
  1206.     // looking for the longest match
  1207.     
  1208.     longest_len=0;
  1209.     posndx=0;
  1210.     
  1211.     while (FastGetEntry(entries,posndx,entry)==noErr){
  1212.         // the entry matches if not_incoming flag bit is clear,
  1213.         // it's longer than the previous match, it's longer than the filename,
  1214.         // and it matches the last N chars of the filename.
  1215.         
  1216.         if ((entry->extension[0]>longest_len)&&(!(entry->flags&ICmap_not_incoming_mask))&&(IsExtensionVar(filename,entry->extension))){
  1217.             // record the new longest entry
  1218.             found_pos=posndx;
  1219.             longest_len=entry->extension[0];
  1220.         }
  1221.         // increment posndx so that we get the next entry the next time around the loop
  1222.         posndx+=entry->total_length;
  1223.     }
  1224.     
  1225.     if (longest_len==0)
  1226.         return icPrefNotFoundErr;
  1227.     
  1228.     return ICRGetMapEntry(inst,entries,found_pos,entry);
  1229. }
  1230.  
  1231. ICError ICRMapEntriesTypeCreator(ICRRecord* inst,Handle entries,OSType fType,OSType fCreator,StringPtr filename,ICMapEntry* entry){
  1232.     ICError err;
  1233.     long posndx,found_pos,match_weight,best_weight;
  1234.     
  1235.     if ((entries==(Handle)0)||(*entries==(Ptr)0))
  1236.         return paramErr;
  1237.     
  1238.     posndx=0L;
  1239.     best_weight=-1L;
  1240.     
  1241.     while (FastGetEntry(entries,posndx,entry)==noErr){
  1242.         if (!(entry->flags&ICmap_not_outgoing_mask)){
  1243.             if (entry->file_type==fType){
  1244.                 match_weight=entry->file_creator==fCreator;
  1245.                 if (IsExtensionVar(filename,entry->extension)){
  1246.                     match_weight+=2*(entry->extension[0]);
  1247.                 }
  1248.                 if (match_weight>best_weight){
  1249.                     // record the new longest entry
  1250.                     found_pos=posndx;
  1251.                     best_weight=match_weight;
  1252.                 }
  1253.             }
  1254.         }
  1255.         posndx+=entry->total_length;
  1256.     }
  1257.     
  1258.     if (best_weight==-1)
  1259.         return icPrefNotFoundErr;
  1260.     
  1261.     return ICRGetMapEntry(inst,entries,found_pos,entry);
  1262. }
  1263.  
  1264. // High Level Mapping Routines
  1265.  
  1266. ICError ICRMapFilename(ICRRecord* inst,StringPtr filename,ICMapEntry* entry){
  1267.     ICError err;
  1268.     Handle entries;
  1269.     ICAttr junk_attr;
  1270.     
  1271.     if (filename[0]==0)
  1272.         return paramErr;
  1273.     
  1274.     err=ICRGetPrefHandle(inst,kICMapping,&junk_attr,&entries);
  1275.     if (err==noErr){
  1276.         err=ICRMapEntriesFilename(inst,entries,filename,entry);
  1277.         DisposeHandle(entries);
  1278.     }
  1279.     
  1280.     return err;
  1281. }
  1282.  
  1283. ICError ICRMapTypeCreator(ICRRecord* inst,OSType fType,OSType fCreator,StringPtr filename,ICMapEntry* entry){
  1284.     ICError err;
  1285.     Handle entries;
  1286.     ICAttr junk_attr;
  1287.     
  1288.     err=ICRGetPrefHandle(inst,kICMapping,&junk_attr,&entries);
  1289.     if (err==noErr){
  1290.         err=ICRMapEntriesTypeCreator(inst,entries,fType,fCreator,filename,entry);
  1291.         DisposeHandle(entries);
  1292.     }
  1293.     
  1294.     return err;
  1295. }
  1296.  
  1297.  
  1298.  
  1299.  
  1300.  
  1301.  
  1302.  
  1303.  
  1304.  
  1305.  
  1306.